Java Project Loom 深度解读:虚拟线程,颠覆高并发的游戏规则 作为深耕架构多年的老司机,我们都清楚:高并发、高吞吐是系统设计的核心挑战,而并发编程则是应对这一挑战的关键武器。 如今,随着 JDK 21之后,Project Loom 携其重磅特性——虚拟线程(Virtual Threads)——正式登场。 二、Project Loom 破局:虚拟线程的奥秘 Project Loom 引入的虚拟线程(Virtual Threads),是 JVM 管理的轻量级线程。其精髓在于与 OS 线程解耦。 四、虚拟线程的战略考量与高阶实践 虚拟线程深刻影响着 Java 应用的架构设计。 资源利用极致化: 依托虚拟线程的轻量级,结构化并发确保底层载体线程被最大化高效复用。 总结 Project Loom 的虚拟线程是 Java 并发编程的一座里程碑。
回顾 Java 传统线程模型的瓶颈及 Project Loom 的设计动机,接着深入剖析虚拟线程的原理、使用方式及调度机制,并结合多种高并发场景给出实战示例。 为了解决这一问题,OpenJDK 社区发起了 Project Loom,引入“虚拟线程”(Virtual Threads),以 JVM 层面的轻量级线程来实现大规模并发。 虚拟线程简介 什么是虚拟线程 虚拟线程是一种由 JVM 调度的轻量级线程类型,不再与 OS 线程一一对应,而是通过“载体线程”(Carrier Threads)复用底层操作系统线程资源。 虚拟线程在准备执行时“挂载”到某个载体线程,执行完毕或遇阻塞时“卸载”挂回队列,载体线程可立即切换到其他挂起的虚拟线程。 0); server.createContext("/", exchange -> { Thread.sleep(10); // 模拟阻塞 byte[] resp = "Hello, Loom
虚拟线程(VirtualThread):由JVM在用户态管理和调度的轻量级线程,数量可以极其庞大(百万级)。一个虚拟线程在其生命周期中,并不会独占一个载体线程。 并将载体线程释放回池中,以便执行其他虚拟线程。 一旦阻塞操作完成(如I/O数据到达),该虚拟线程会被重新调度到某个载体线程上继续执行。关键洞见:虚拟线程的“阻塞”是廉价的。 4.1避免在虚拟线程中执行CPU密集型任务虚拟线程的优势在于处理I/O等待。 4.2谨慎使用synchronized和ReentrantLock虽然虚拟线程支持synchronized,但如果一个虚拟线程在持有锁的同时执行了阻塞I/O操作,那么它所占用的载体线程也会被阻塞,无法执行其他虚拟线程
但随着 Java 21 的发布,Project Loom 带来的虚拟线程正式转正。这一刻,Java 终于补齐了它在并发领域最后的短板。 二、 破局:Java 21 虚拟线程的“黑科技” Java 21 引入了虚拟线程(Virtual Thread),它彻底改变了游戏规则。 1. 搬运工模型:载体线程与虚拟线程 虚拟线程不再直接映射内核线程。它引入了一个“中间层”: 虚拟线程 (Virtual Thread):极其轻量,一个对象只占几百字节,可以随手创建几百万个。 当你在虚拟线程里发起一个阻塞的 IO 调用(比如 Socket.read())时: 挂起(Yield):JVM 会感知到阻塞,它会自动把当前虚拟线程的栈帧(Stack Frames)从堆外内存拷贝到 四、 巅峰对决:Java Loom vs Go Goroutine 既然两者的原理相似,那么 Java 的这次升级真的能反杀吗?我们从三个维度来看: 1.
第二章:核心支柱一——虚拟线程(VirtualThreads)2.1虚拟线程的本质:JVM之上的轻量级协程虚拟线程并非一个全新的概念,其思想源于计算机科学中的协程(Coroutine)。 当虚拟线程遇到阻塞操作(如Thread.sleep()、Socket.read())时,JVM会将其从载体线程上卸载(Unmount),并将载体线程释放回池中,以便执行其他虚拟线程。 阻塞操作完成后,虚拟线程会被重新调度到某个载体线程上继续执行。关键洞见:虚拟线程的阻塞是廉价的。它不会阻塞底层的操作系统线程,只是将自身的执行状态(栈帧)保存起来,等待I/O完成后再恢复。 这使得成千上万个虚拟线程可以高效地复用少量的载体线程。 不可变性缺失:ThreadLocal的值是可变的,容易引发线程安全问题。与虚拟线程不匹配:虚拟线程是短暂且大量的,为每个虚拟线程维护一个ThreadLocal副本效率低下。
我在Unity中开启了一个线程来做下载任务,然后实时刷新下载进度。然后Unity报了一个错误。 意思是Unity中的组件只能运行在Unity的主线程中,无法在新开的线程中调用Unity的组件。 用Loom实现多线程与主线程交互 using UnityEngine; using System.Collections; using System.Collections.Generic; using (); // 用Loom的方法调用一个线程 Loom.RunAsync( () => { 的方法在Unity主线程中调用Text组件 Loom.QueueOnMainThread((param) => { mText.text
作者 | Michael Redlich 译者 | 刘雅梦 策划 | 丁晓昀 Java 近期新闻综述,包括来自 OpenJDK、JEP 425、JDK 19、Loom 项目的 19- OpenJDK JEP 425,虚拟线程(预览版),从其 JEP 草案(Draft)8277131 提升为候选(Candidate)状态。 该 JEP 将虚拟线程引入到 Java 平台中,这是一种轻量级线程,可以极大地减少编写、维护及观测高吞吐量并发应用程序的工作量。 JFR 堆栈跟踪、线程 ID 和时间事件中的能力。 Loom 项目 Loom 项目的早期访问构建版本的 19-loom+5-429 版已经面向 Java 社区发布,它是基于 JDK 19 早期访问构建版本的第 16 版的。
Project Loom已通过JEP 425进入JDK。它自 2022 年 9 月的 Java 19 起作为预览功能提供。其出现的目的就是为了显著减少编写、维护和提高并发应用程序的吞吐量的。 Runnable Project Loom 重新访问了 Java 运行时库中的所有区域,这些区域可以阻止和更新代码,以便在代码遇到阻塞时生成代码。 在成为虚拟线程方案中的最佳公民的道路上,我们将进一步重新审视 I/O 或其他阻塞代码上下文中的使用情况,以避免平台线程固定在热代码路径中,以便您的应用程序可以充分利用 Project Loom。 如果我们了解了核心框架中面向虚拟线程的优化的具体潜力,无论是某些使用点还是某些使用,我们将尝试在即将推出的 Spring 框架和 Spring Boot 维护版本中尽可能将相应的改进纳入,甚至在 Loom 其中许多项目都意识到需要改善他们的行为,以释放Project Loom的全部潜力。synchronized 您的应用程序是否会从虚拟线程中受益? 这是一个比好处更具体的问题,也是一个更难回答的问题。
大家好,我是不才陈某~ 在这篇文章中,我们将看到如何在spring-boot中利用loom虚拟线程。我们还将在JMeter的帮助下做一些负载测试,看看虚拟线程和普通线程的响应时间如何。 首先,虚拟线程是 Project Loom 的一部分。 此外,Loom 不会加速内存计算,例如并行流,这不是 Loom 的目标。 我在这篇博客中详细讨论了这一点: https://medium.com/@anil.java.story/project-loom-virtual-threads-part-1-b17e327c8ba7 > 由于 Project Loom 处于预览阶段,我们需要启用预览功能。 现在让我们在启用虚拟线程功能的情况下运行负载测试。
BufferedInputStream 作为 Java I/O 体系中的经典缓冲装饰器,其设计哲学、源码实现及与现代并发模型(如 Project Loom 虚拟线程)的协同优化,值得深入剖析。 3.2 Project Loom(虚拟线程)的协同优化 Java 21+ 引入的 虚拟线程(Virtual Threads) 改变了并发 I/O 的游戏规则: 轻量级:百万级虚拟线程 vs 传统线程的千级上限 ; 阻塞即挂起:I/O 阻塞时自动挂起虚拟线程,释放底层载体线程。 实测数据: 在 10K 虚拟线程并发读取 1MB 文件场景下, 传统线程 + BufferedInputStream:吞吐量 ~12,000 req/s 虚拟线程 + BufferedInputStream 每个虚拟线程应创建独立的 BufferedInputStream 实例。
Java 19 已经于日前发布,其中最引人注目的特性就要数虚拟线程了,本文介绍了 Loom 项目中虚拟线程和结构化编程的基础知识,并将其与操作系统线程进行了对比分析。 Loom 项目旨在通过引入两个新特性来解决当前并发模型中的这些问题,即虚拟线程(virtual thread)和结构化并发(structured concurrency)。 虚拟线程 Thread.startVirtualThread(() -> { System.out.println("Hello, Project Loom!") 4 Loom 项目状况 Loom 项目开始于 2017 年,经历了许多变化和提议。虚拟线程最初被称为 fibers,但后来为了避免混淆而重新进行了命名。 .html Project Loom: Modern Scalable Concurrency for the Java Platform https://www.youtube.com/watch?
随着 Java 21 LTS 及后续版本的发布,函数式编程 的深度演进和 虚拟线程 (Project Loom) 的横空出世,Java正以前所未有的姿态拥抱高并发和简洁性! 而到了Java 21,革命性的**虚拟线程(Project Loom)**作为LTS版本的新特性正式发布,更是彻底改变了我们对Java并发模型的认知。 虚拟线程(Project Loom)的革命性:高并发的“轻量级”利器 如果说函数式编程让Java代码更优雅,那么虚拟线程(Virtual Threads),也就是Project Loom的成果,则是彻彻底底地改变了 什么是虚拟线程(Loom):轻装上阵的并发模型 虚拟线程是JVM层面实现的用户模式线程,它们是轻量级的,由JVM而非操作系统进行调度。 Concurrency in Java with Project Loom Java Stream API Tutorial
为了解决这一问题,Project Loom引入了革命性的Virtual Thread(虚拟线程),并重新定义了ThreadPool(线程池)的角色。 第三章:Virtual Thread(虚拟线程)——Loom项目带来的轻量级革命3.1 定义与实现机制Virtual Thread(虚拟线程) 是由JVM用户态管理的轻量级线程,由 Project Loom 第四章:ThreadPool(线程池)——从实线程管理者到虚拟线程调度器4.1 传统角色:管理 Platform Thread(实线程)在 Virtual Thread(虚拟线程) 出现之前,ThreadPool 4.2 新时代角色:承载 Virtual Thread(虚拟线程) 的载体有了 Virtual Thread(虚拟线程) 后,我们还需要 ThreadPool(线程池) 吗? 对于 Virtual Thread(虚拟线程): 不需要。因为 Virtual Thread(虚拟线程) 本身开销极低,可以直接创建和丢弃,无需池化。
然而,异步编程也带来了诸多挑战,如回调地狱、线程管理、异常处理等。本文旨在拆解这些难题并探讨解决方案。 Java中常见的异步编程框架(如Netty、Spring WebFlux) 常见的异步编程难题 回调地狱问题 嵌套回调导致代码难以维护 解决方案:使用CompletableFuture或反应式编程简化逻辑 线程管理与资源消耗 线程池配置不当导致的性能问题 异步任务对系统资源的过度占用 解决方案:合理配置线程池,使用虚拟线程(Loom项目) 异常处理困难 异步任务中的异常难以捕获和传递 解决方案:利用CompletableFuture.exceptionally WebFlux实现非阻塞IO 示例代码展示如何通过Flux和Mono处理流式数据 性能调优与监控 异步任务的性能瓶颈定位 使用Micrometer或Prometheus监控异步任务 未来趋势 Java虚拟线程 (Project Loom)的潜力 反应式编程与协程的结合 总结 异步编程虽然复杂,但通过合理选择工具和模式可以有效解决问题。
值得一提的是,开发者可通过此版本在基于 Spring 的应用中体验 “虚拟线程”(JDK 19 中的预览版 “Project Loom”),现在提供了自定义选项来插入基于虚拟线程的 Executor 实现 ,目标是在 Project Loom 正式可用时提供 “一等公民” 的配置选项。
依然发现了一些值得关注的新闻,包括:Brian Goetz 撰写的由三部分组成的博客系列“Valhalla 项目的现状”;GlassFish 7.0.0-M1;Nicolai Parlog 创建的新项目 Project Loom Lab;Jakarta EE 教程更新至 Jakarta EE 9.1;Apache Camel 3.11.5 以及 JDKMon 17.0.21。 Loom 项目 甲骨文公司的 Java 开发者倡导者 Nicolai Parlog 在推特上介绍了 Loom Lab 项目,该项目包含了两个应用,其中一个是文件夹大小分析器,另外一个是 echo 服务器 ,分别都基于虚拟线程和非虚拟线程来实现。 该项目需要最新的 Loom 早期访问构建版本和 Maven。
Java 中的虚拟线程,也叫做协程或“轻量级线程”,它诞生于 JDK 19(预览 API),正式发布于 JDK 21,它是一种在 Java 虚拟机(JVM)层面实现的逻辑线程,不直接和操作系统的物理线程一一对应 操作系统线程、普通线程(Java 线程)和虚拟线程的关系如下:虚拟线程使用虚拟线程的创建方式,主要有以下 4 种:Thread.startVirtualThread(Runnable task)Thread.ofVirtual (()->{ System.out.println("Do virtual thread.");});// 运行虚拟线程vt.start();3.factory先创建虚拟线程工厂,然后再使用工厂创建虚拟线程 普通线程默认创建的是用户线程(而守护线程),而虚拟线程是守护线程,并且其守护线程的属性不能被修改,如果修改就会报错,如下图所示:虚拟线程由 JVM 调度和使用,避免了普通线程频繁切换的性能开销,所以相比于普通的线程来说 小结线程是轻量级的进程,而虚拟线程则是轻量级的线程,虚拟线程是 JVM 层面实现的逻辑线程,不直接和操作系统的物理线程一一对应,因此使用它可以减少线程上下文切换所带来的性能开销。
API和矢量API),以及与 Project Loom 相关的功能(作用域值、虚拟线程和结构化并发),这些功能将大大简化编写、维护和观察高吞吐量并发应用程序的过程。 Project Loom Preview/Incubator Features JEP 429: Scoped Values (Incubator): Enables the sharing of immutable 它们优于线程局部变量,尤其是在使用大量虚拟线程时。 虚拟线程 (Virtual Threads) 进入第 2 预览阶段 为 Java 引入虚拟线程,虚拟线程是 JDK 实现的轻量级线程,它在其他多线程语言中已经被证实是十分有用的,比如 Go 中的 Goroutine 以前称为范围局部变量(孵化器),在 Project Loom 的支持下,此功能建议在线程内和线程之间共享不可变数据。这优先于线程局部变量,尤其是在使用大量虚拟线程时。
面试官:单线程能不能实现多并发 普通回答:嗯?(内心OS:单线程怎么可能支持多并发呢,面试官在搞什么鬼啊) 在计算机编程中,单线程通常指的是程序只有一个执行线程,在任意时刻只能执行一个任务。 具体实现可参考文章: https://developer.aliyun.com/article/1290951#slide-18 如果在早期版本中依然想使用协程的话,可参照如下方式: 使用第三方库:例如Quasar、Project Loom等,这些库通过使用Fiber(纤程)或类似的机制实现协程,可以在Java中实现轻量级的并发任务 使用Project Loom的Virtual Threads:Project Loom是一个在Java 中实现轻量级线程的项目,其中Virtual Threads(虚拟线程)可以使用类似协程的功能。 Virtual Threads是一种更轻量级的线程,可以更高效的处理大量并发任务 使用Reactive编程:使用列斯Reactive Streams的编程模型,如RxJava、Project Reactor
值得一提的是,开发者可通过此版本在基于 Spring 的应用中体验 “虚拟线程”(JDK 19 中的预览版 “Project Loom”),文末阅读原文可了解更多细节。 现在提供了自定义选项来插入基于虚拟线程的 Executor 实现,目标是在 Project Loom 正式可用时提供 “一等公民” 的配置选项。